﻿using Dapper;
using EquipmentModule.Contracts;
using EquipmentModule.Entity;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
using System.Text;

namespace EquipmentModule.Services
{
    /// <summary>
    /// 设备服务
    /// </summary>
    public class EquipmentService : IEquipmentService
    {
        /// <summary>
        /// 添加设备
        /// </summary>
        /// <param name="info"></param>
        /// <param name="dbStr"></param>
        public void Add(Equipment info, string dbStr = null)
        {
            if (info.MachineType==Util.MachineType4毫厘接口)
            {
                //获取设备
                if (String.IsNullOrEmpty(info.Token) || string.IsNullOrEmpty(info.ProjectId)) return;
                try
                {
                    HttpClient client = new HttpClient();
                    client.DefaultRequestHeaders.Add("Haoli-Api-Token", info.Token);
                    var response = client.GetAsync($"https://haoli.tech/api/project/{info.ProjectId}/station/");
                    response.Wait();
                    response.Result.EnsureSuccessStatusCode();
                    var res = response.Result.Content.ReadAsStringAsync();
                    res.Wait();
                    List<Equipment4API> data = JsonConvert.DeserializeObject<List<Equipment4API>>(res.Result);
                    List<Equipment> list = new List<Equipment>();
                    foreach (var item in data)
                    {
                        Equipment equipment = info.Clone() as Equipment;
                        equipment.DevId = item.Id;
                        equipment.Name = item.Name;
                        equipment.X = item.Lng;
                        equipment.Y = item.Lat;
                        equipment.ProjectId = info.ProjectId;
                        equipment.Token = info.Token;
                        list.Add(equipment);
                    } 
                    List<Equipment> equipments = (List<Equipment>) QueryByProjectId(info.ProjectId);
                    list.RemoveAll(item =>
                    {
                        foreach (var equipment in equipments)
                        {
                            if (item.DevId == equipment.DevId)
                            {
                                return true;
                            }
                        }
                        return false;
                    });
                    using var db = EquipmentModule.ConnCache.GetConn(dbStr);
                    // db.Execute("DELETE FROM Md_Equipment WHERE ProjectId=@ProjectId",new { info.ProjectId});
                    db.Execute("INSERT INTO [dbo].[Md_Equipment]([Id],[DevId],[Name],[Status],[Location],[X],[Y],[SN],[PN],[Specification],[Origin],[Supplier],[SupplyTime],[Description],[CreateTime],[SectionId],[Url],[Token],[Maintenance],[Operator],[ContractWay],[ImageUrl],[ProjectId],[MachineType])  VALUES(newid(),@DevId,@Name,@Status,@Location,@X,@Y,@SN,@PN,@Specification,@Origin,@Supplier,@SupplyTime,@Description,getdate(),@SectionId,@Url,@Token,@Maintenance,@Operator,@ContractWay,@ImageUrl,@ProjectId,@MachineType)", list);

                }
                catch (Exception ex)
                {
                }
            }
            else if (info.MachineType == Util.MachineType4流向仪)
            {
                //获取设备
                if (String.IsNullOrEmpty(info.Token) || string.IsNullOrEmpty(info.ProjectId)) return;
                var body = JsonConvert.SerializeObject(new { orgId=info.ProjectId, apiKey=info.Token });
                try
                {
                    HttpClient client = new HttpClient();
                    var response = client.PostAsync($"http://www.bjutsg.com/console/api/bojoe/getDeviceInfo.json",new StringContent(body));
                    response.Wait();
                    response.Result.EnsureSuccessStatusCode();
                    var res = response.Result.Content.ReadAsStringAsync();
                    res.Wait();
                    Respones4FlowChat data = JsonConvert.DeserializeObject<Respones4FlowChat>(res.Result);
                    if (data == null || data.Code != "200") return;
                    List<Equipment> list = new List<Equipment>();
                    foreach (var item in data.Data)
                    {
                        Equipment equipment = info.Clone() as Equipment;
                        equipment.DevId = item.DeviceId;
                        equipment.Name = item.Name;
                        equipment.X = item.X;
                        equipment.Y = item.Y;
                        equipment.Location = item.Address;
                        equipment.CreateTime = item.UpdateDeviceTime;
                        equipment.ProjectId = info.ProjectId;
                        equipment.Token = info.Token;
                        list.Add(equipment);
                    }
                    List<Equipment> equipments = (List<Equipment>) QueryByProjectId(info.ProjectId);
                    list.RemoveAll(item =>
                    {
                        foreach (var equipment in equipments)
                        {
                            if (item.DevId == equipment.DevId)
                            {
                                return true;
                            }
                        }
                        return false;
                    });
                    using var db = EquipmentModule.ConnCache.GetConn(dbStr);
                    // db.Execute("DELETE FROM Md_Equipment WHERE ProjectId=@ProjectId", new { info.ProjectId });
                    db.Execute("INSERT INTO [dbo].[Md_Equipment]([Id],[DevId],[Name],[Status],[Location],[X],[Y],[SN],[PN],[Specification],[Origin],[Supplier],[SupplyTime],[Description],[CreateTime],[SectionId],[Url],[Token],[Maintenance],[Operator],[ContractWay],[ImageUrl],[ProjectId],[MachineType])  VALUES(newid(),@DevId,@Name,@Status,@Location,@X,@Y,@SN,@PN,@Specification,@Origin,@Supplier,@SupplyTime,@Description,getdate(),@SectionId,@Url,@Token,@Maintenance,@Operator,@ContractWay,@ImageUrl,@ProjectId,@MachineType)", list);
                }
                catch (Exception ex)
                {
                }
            }
            else
            {
                info.Id = Guid.NewGuid();
                if (string.IsNullOrEmpty(info.DevId))
                {
                    info.DevId = info.Id.ToString();
                }

                Console.WriteLine(info.poll);
                using var db = EquipmentModule.ConnCache.GetConn(dbStr);
                db.Execute("INSERT INTO [dbo].[Md_Equipment]([Id],[DevId],[Name],[Status],[Location],[X],[Y],[SN],[PN],[Specification],[Origin],[Supplier],[SupplyTime],[Description],[CreateTime],[SectionId],[Url],[Token],[Maintenance],[Operator],[ContractWay],[ImageUrl],[MachineType],[poll])  VALUES(@Id,@DevId,@Name,@Status,@Location,@X,@Y,@SN,@PN,@Specification,@Origin,@Supplier,@SupplyTime,@Description,getdate(),@SectionId,@Url,@Token,@Maintenance,@Operator,@ContractWay,@ImageUrl,@MachineType,@poll)", info);
            }
        }

        public void Update(Equipment info, string dbStr = null)
        {
            if (info.Id == null) return;
            //写sql语句
            StringBuilder sql = new StringBuilder();
            sql.AppendLine("UPDATE  [dbo].[Md_Equipment] SET");
            if (info.DevId !=null)
            {
                sql.AppendLine("[DevId] = @DevId,");
            }

            if (info.ProjectId!=null)
            {
                sql.AppendLine("[ProjectId] = @ProjectId,");
            }
            
            if (info.Name!=null)
            {
                sql.AppendLine("[Name] = @Name,");
            }
            
            if (info.Status!=null)
            {
                sql.AppendLine("[Status] = @Status,");
            }
            
            if (info.MachineType!=null)
            {
                sql.AppendLine("[MachineType] = @MachineType,");
            }
            
            if (info.Location!=null)
            {
                sql.AppendLine("[Location] = @Location,");
            }
            if (info.X!=null)
            {
                sql.AppendLine("[X] = @X,");
            }
            if (info.Y!=null)
            {
                sql.AppendLine("[Y] = @Y,");
            }
            if (info.SN!=null)
            {
                sql.AppendLine("[SN] = @SN,");
            }
            if (info.PN!=null)
            {
                sql.AppendLine("[PN] = @PN,");
            }if (info.Specification!=null)
            {
                sql.AppendLine("[Specification] = @Specification,");
            }
            if (info.Origin!=null)
            {
                sql.AppendLine("[Origin = @Origin,");
            }
            if (info.Supplier!=null)
            {
                sql.AppendLine("[Supplier] = @Supplier,");
            }
            if (info.Description!=null)
            {
                sql.AppendLine("[Description] = @Description,");
            }
            if (info.Url!=null)
            {
                sql.AppendLine("[Url] = @Url,");
            }
            if (info.Maintenance!=null)
            {
                sql.AppendLine("[Maintenance] = @Maintenance,");
            }
            if (info.Operator!=null)
            {
                sql.AppendLine("[Operator] = @Operator,");
            }
            if (info.ContractWay!=null)
            {
                sql.AppendLine("[ContractWay] = @ContractWay,");
            }
            if (info.ImageUrl!=null)
            {
                sql.AppendLine("[ImageUrl] = @ImageUrl,");
            }

            if (info.poll !=null)
            {
                sql.AppendLine("[poll] = @poll,");
            }
            sql.AppendLine("[SectionId] = @SectionId");
            sql.AppendLine("WHERE [id]=@id");
            using var db = EquipmentModule.ConnCache.GetConn();
            db.Execute(sql.ToString(),info);
        }

        public void Del(Guid id, string dbStr = null)
        {
            using var db = EquipmentModule.ConnCache.GetConn(dbStr);
            db.Execute("DELETE FROM Md_Equipment WHERE Id=@id", new { id });
        }

        public IEnumerable<DownListInfo> DownList(string dbStr = null)
        {
            using var db = EquipmentModule.ConnCache.GetConn(dbStr);
            return db.Query<DownListInfo>("SELECT DevId AS Value,Name AS Name FROM [dbo].[Md_Equipment]");
        }

        public IEnumerable<Equipment> Index(Guid? id,Guid? sassId,string user=null,string name=null, string dbStr = null)
        {
            //获取区域树
            StringBuilder sql = new StringBuilder();
            sql.AppendLine("WITH  CTE AS( ");
            sql.AppendLine("    SELECT Id,Name,ParentId,Level,X,Y,CreateTime FROM Md_Section WHERE Id=@id");
            sql.AppendLine("    UNION ALL SELECT T.Id,T.Name,T.ParentId,T.Level,T.X,T.Y,T.CreateTime FROM Md_Section AS t");
            sql.AppendLine("    JOIN CTE AS a ON T.ParentId = A.Id");
            sql.AppendLine(")");
            sql.AppendLine("SELECT Id FROM CTE ORDER BY Level;");
            using var db = EquipmentModule.ConnCache.GetConn();
            var ids = db.Query<Guid>(sql.ToString(), new { id }).ToList();
            sql.Clear();
            if (!string.IsNullOrEmpty(dbStr)&& dbStr.ToLower()!=Util.BaseDB)
            {
                sql.AppendLine("SELECT A.*,B.Name AS SectionName ");
                sql.AppendLine("FROM Md_Equipment A ");
                sql.AppendLine("LEFT JOIN SOADB.dbo.Md_Section B ON A.SectionId=b.Id ");
                sql.AppendLine("WHERE 1=1");
                if (id != null)
                {
                    sql.AppendLine("AND  (A.SectionId IN @ids OR A.Id=@id) ");
                }
                if (!string.IsNullOrEmpty(name))
                {
                    sql.AppendLine("AND A.NAME LIKE '%'+@name+'%'");
                }
                if (!string.IsNullOrEmpty(user))
                {
                    sql.AppendLine("AND A.Operator LIKE '%'+@user+'%'");
                }
                db.Dispose();
                using var db1 = EquipmentModule.ConnCache.GetConn(dbStr);
                return db1.Query<Equipment>(sql.ToString(), new { ids, id, sassId, user, name });
            }
            else
            {
                sql.AppendLine("SELECT A.*,B.Name AS SectionName ");
                sql.AppendLine("FROM Md_Equipment A ");
                sql.AppendLine("LEFT JOIN Md_Section B ON A.SectionId=b.Id ");
                sql.AppendLine("LEFT JOIN Md_EquipmentSass  ES ON A.Id=ES.EquipmentId ");
                sql.AppendLine("WHERE 1=1");
                if (id != null)
                {
                    sql.AppendLine("AND  (A.SectionId IN @ids OR A.Id=@id) ");
                }
                if (sassId != null)
                {
                    sql.AppendLine("AND (ES.SassId=@sassId OR @sassId IS NULL) ");
                }
                if (!string.IsNullOrEmpty(name))
                {
                    sql.AppendLine("AND A.NAME LIKE '%'+@name+'%'");
                }
                if (!string.IsNullOrEmpty(user))
                {
                    sql.AppendLine("AND A.Operator LIKE '%'+@user+'%'");
                }
                return db.Query<Equipment>(sql.ToString(), new { ids, id, sassId, user, name });
            }
        }
        /// <summary>
        /// 分享设备
        /// </summary>
        /// <param name="info"></param>
        public void ShareEquipment(EquipmentSassInfo info)
        {
            using var db = EquipmentModule.ConnCache.GetConn();
            //0.获取所有的Sass账号
            var sass = db.Query<Sass>("SELECT * FROM Sys_Sass").ToList();
            //1.获取现有的绑定
            var exists= db.Query<Guid>("SELECT SassId FROM Md_EquipmentSass WHERE EquipmentId=@id", new { id = info.EquipmentId });
            foreach (var item in info.SassId)
            {
                //如果已经分享
                if (exists.Contains(item)) continue;
                //如果没有分享
                //1.1 插入关系表
                db.Execute("INSERT INTO Md_EquipmentSass(EquipmentId,SassId) VALUES(@equipmentId,@sassId)", new { sassId=item,equipmentId=info.EquipmentId});
                //1.2 将设备插入账套数据库
                var sassItem = sass.Find(x => x.Id == item);
                if (sassItem!=null)
                {
                    using (var dbSub = EquipmentModule.ConnCache.GetConn(sassItem.DB))
                    {
                        dbSub.Execute("INSERT INTO Md_Equipment SELECT * FROM SOADB.dbo.Md_Equipment A WHERE A.Id=@id", new { id = info.EquipmentId });
                    }
                }
            }
        }

        public IEnumerable<Equipment> QueryByProjectId(string ProjectId)
        {
            using var db = EquipmentModule.ConnCache.GetConn();
            return db.Query<Equipment>("SELECT * FROM Md_Equipment  WHERE [ProjectId] = @ProjectId", new { ProjectId });
        }

        public IEnumerable<Equipment> QueryByMachineType(string MachineType)
        {
            using var db = EquipmentModule.ConnCache.GetConn();
            return db.Query<Equipment>("SELECT * FROM Md_Equipment  WHERE [MachineType] = @MachineType", new { MachineType });
        }
    }
}
